#ifndef _I_BUFFER_2D_H_
#define _I_BUFFER_2D_H_

#include "../interface/I_Buffer.h"

//////////////////////////////////////////////////////////////////////////
/// I_Buffer2D is an interface for handling memory as a 2D surface
/// on cpu and cuda / d3d / ogl devices
//////////////////////////////////////////////////////////////////////////
class I_Buffer2D
{
	template <class T> friend class T_Buffer2D_CU;
	template <class T> friend class T_Buffer2D_GL;

protected:
	int					m_width, m_height, m_pitch;
	I_Buffer	*	m_pBuffer;

public:
	I_Buffer2D(void)
	{  
		m_height = m_width = m_pitch = 0; 
		m_pBuffer = NULL;
	}
	virtual ~I_Buffer2D(void) {}

	virtual void        Create(int nWidth, int nHeight, int nPitch, I_api_Device *pDevice = NULL)=0;
	virtual void        Create(int nWidth, int nHeight, int nPitch, I_Buffer * pShared)=0;
	virtual bool        Request(int nWidth, int nHeight, int nPitch, int * pOffset, void **hPtr, void **dPtr, void ** bPtr)=0;

	//////////////////////////////////////////////////////////////////////////
	/// Since this is a 2D representation of data in some case one would want
	/// copy or replace a rectangular section of the buffer. To do that
	/// there is a different interface that 
	//////////////////////////////////////////////////////////////////////////
	virtual	void				Memcpy(int32 nDir, 
														 int32 nStartR = 0, int32 nStartC = 0, 
														 int32 nStopR = 0, int32 nStopC = 0) = 0;
	virtual	void				Memset(void *pElem, 
														 int32 nStartR = 0, int32 nStartC = 0, 
														 int32 nStopR = 0, int32 nStopC = 0) = 0;

	//////////////////////////////////////////////////////////////////////////
	/// Get buffer sizes along WH and P dimensions
	//////////////////////////////////////////////////////////////////////////
	virtual int							Width(){ return m_width; }
	virtual int							H(){ return m_height; }
	virtual int							P(){ return m_pitch; }

	virtual void						Width(int w){ m_width = w; }
	virtual void						H(int h){ m_height = h; }
	virtual void						P(int p){ m_pitch = p; }

	virtual int							Size() { return m_pBuffer->Size(); }
	virtual void					*	hPtr() { return m_pBuffer->hPtr(); }
	virtual void					*	dPtr() { return m_pBuffer->dPtr(); }
	virtual I_api_Buffer	*	bufferPtr(){ return m_pBuffer->bufferPtr(); }
	virtual I_Buffer			*	pBuffer(){ return m_pBuffer; }
};

#endif